package com.ts.api.task.log;

import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.valid.ValidParam;
import com.ts.api.common.constant.api.ApiEnum;
import com.ts.api.module.api.dao.ApiLogDao;
import com.ts.api.module.api.entity.po.ApiLogPO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentLinkedDeque;

/**
 *  日志异步线程池
 */
@Component
public class ApiLogExecute {

    private static ConcurrentLinkedDeque<ApiLogPO> LOG_DEQUE = new ConcurrentLinkedDeque<>();
    private static ConcurrentLinkedDeque<ApiLogPO> ERROR_LOG_DEQUE = new ConcurrentLinkedDeque<>();

    @Autowired
    private ApiLogDao apiLogDao;

    /** 批量长度 */
    private int batchSize = 100;

    public ApiLogExecute() {
        super();
        startLogBatchInsert();
        startErrorLogBatchInsert();
    }

    /**
     *  普通日志-执行批量插入操作
     */
    void startLogBatchInsert() {
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    List<ApiLogPO> list = CollUtils.newArrayList();
                    Iterator<ApiLogPO> iterator = LOG_DEQUE.iterator();
                    while (iterator.hasNext()) {
                        list.add(iterator.next());
                        iterator.remove();
                    }

                    if (ValidParam.isEmpty(list)) {
                        return ;
                    }

                    if (list.size() > batchSize) {
                        CollUtils.batchProcess(list, batchSize, (pageList) -> apiLogDao.batchInsert(pageList));
                    } else {
                        apiLogDao.batchInsert(list);
                    }
                } catch (Exception e) {
                    // do nothing
                }
            }
        }, 0, 500l);
    }

    /**
     *  特殊日志-执行批量插入操作
     */
    void startErrorLogBatchInsert() {
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    List<ApiLogPO> list = CollUtils.newArrayList();
                    Iterator<ApiLogPO> iterator = ERROR_LOG_DEQUE.iterator();
                    while (iterator.hasNext()) {
                        list.add(iterator.next());
                        iterator.remove();
                    }

                    if (ValidParam.isEmpty(list)) {
                        return ;
                    }

                    if (list.size() > 100) {
                        CollUtils.batchProcess(list, batchSize, (pageList) -> apiLogDao.batchInsert(pageList));
                    } else {
                        apiLogDao.batchInsert(list);
                    }

                } catch (Exception e) {
                    // do nothing
                }
            }
        }, 0, 500l);
    }

    /**
     *  异步执行
     */
    public void execute(ApiLogPO logPO) {
        if (Eq.str(logPO.getEventCode(), Integer.toString(ApiEnum.API_DATA_EXCHANGE_DISCARD.getCode()))) {
            ERROR_LOG_DEQUE.add(logPO);
        } else {
            LOG_DEQUE.add(logPO);
        }
    }
}
